package com.xpq.petserver.service.impl;

import com.xpq.petserver.entity.DO.User;
import com.xpq.petserver.entity.DTO.*;
import com.xpq.petserver.entity.VO.UserInfoVO;
import com.xpq.petserver.entity.response.GeneralResponse;
import com.xpq.petserver.entity.response.LoginResponse;
import com.xpq.petserver.mapper.UserMapper;
import com.xpq.petserver.service.UserService;
import com.xpq.petserver.util.GetTimeUtils;
import com.xpq.petserver.util.JWTUtils;
import com.xpq.petserver.util.PathUtils;
import com.xpq.petserver.util.mapstruct.UserConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Date;
import java.util.HashMap;
import java.util.regex.Pattern;

/**
 * 用户表相关业务
 * @author XPQ
 * @date 2022-04-01
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    /**
     * 注册用户业务
     * @param registerUserDTO 新用户信息
     * @return
     */
    @Override
    public GeneralResponse registerUser(RegisterUserDTO registerUserDTO) {
        GeneralResponse generalResponse = new GeneralResponse();
        // 手机号不为空或空串
        boolean isPhoneNotNull = registerUserDTO.getPhone() != null && registerUserDTO.getPhone() != "";
        // 密码不为空或空串或空串的md5加密
        boolean isPasswordNotNull = registerUserDTO.getPassword() != null
                && registerUserDTO.getPassword() != ""
                && registerUserDTO.getPassword() != DigestUtils.md5DigestAsHex("".getBytes());
        // 手机号不包含空格
        boolean isPhoneNoSpace = Pattern.matches("^[^\\s]*$", registerUserDTO.getPhone());

        try {
            // 如果账号密码都不为空
            if (isPhoneNotNull && isPasswordNotNull) {
                // 如果手机号包含了空格
                if( !isPhoneNoSpace ) {
                    generalResponse.setCode(400);
                    generalResponse.setMsg("手机号不能包含空格！");
                    return generalResponse;
                }
                // 生成账号、创建时间、修改时间
                registerUserDTO.setId("pet_" + System.currentTimeMillis());
                registerUserDTO.setCreateTime(GetTimeUtils.getCurrentTime());
                registerUserDTO.setUpdateTime(GetTimeUtils.getCurrentTime());
                // 密码前端后端双重md5加密
                registerUserDTO.setPassword(DigestUtils.md5DigestAsHex(registerUserDTO.getPassword().getBytes()));
                userMapper.createUser(registerUserDTO);
                generalResponse.setCode(200);
                generalResponse.setMsg("注册成功！");
            }else {
                generalResponse.setCode(400);
                generalResponse.setMsg("账号或密码不能为空！");
            }
        }catch (DuplicateKeyException e) {// 注册手机号重复异常
            e.printStackTrace();
            generalResponse.setCode(500);
            generalResponse.setMsg("账号已被注册！");
        }catch (Exception e) {
            e.printStackTrace();
            generalResponse.setCode(500);
            generalResponse.setMsg("注册失败！");
        }

        return generalResponse;
    }

    /**
     * 用户登录服务
     * @param loginDTO 用户登录信息
     * @return
     */
    @Override
    public LoginResponse login(LoginDTO loginDTO) {
        LoginResponse loginResponse = new LoginResponse();

        try{
            User user = userMapper.selectUserByPhone(loginDTO.getPhone());

            // 用户不存在
            if (user == null) {
                loginResponse.setCode(400);
                loginResponse.setMsg("账号或密码错误！");
                return loginResponse;
            }
            // 用户存在且密码正确
            if((DigestUtils.md5DigestAsHex(loginDTO.getPassword().getBytes())).equals(user.getPassword())) {
                // 加上用户相关信息生成token
                String token = JWTUtils.getToken(user.getId());
                // 设置响应信息返回给用户
                loginResponse.setCode(200);
                loginResponse.setMsg("登录成功！");
                loginResponse.setToken(token);
                HashMap<String, String> map = new HashMap<>();
                map.put("avatarPath", PathUtils.getAvatarLogicalPath() + user.getAvatar());
                loginResponse.setData(map);
            }else {
                loginResponse.setCode(400);
                loginResponse.setMsg("账号或密码错误！");
            }
        }catch (Exception e) {
            e.printStackTrace();
            loginResponse.setCode(500);
            loginResponse.setMsg("登录失败！");
        }
        return loginResponse;
    }

    /**
     * 判断用户是否已登录
     * @param id 用户id
     * @return 用户头像地址
     */
    @Override
    public GeneralResponse isLogin(String id) {
        GeneralResponse generalResponse = new GeneralResponse();

        User user = userMapper.selectUserById(id);
        // 如果昵称为空则账号作为昵称
        user.setNickname(user.getNickname() == null ? user.getId() : user.getNickname());
        // 如果用户头像不为空，则返回完整的url地址
        user.setAvatar(user.getAvatar() == null ? null : (PathUtils.getAvatarLogicalPath() + user.getAvatar()));
        generalResponse.setCode(200);
        generalResponse.setMsg("用户已登录！");
        UserInfoVO userInfoVO = UserConverter.INSTANCT.toUserInfoVO(user);
        generalResponse.setData(userInfoVO);
        return generalResponse;
    }


    /**
     * 上传修改用户头像
     * @param avatar 用户上传的头像文件
     * @param userId 用户的id
     * @return
     */
    @Override
    public GeneralResponse uploadAvatar(MultipartFile avatar, String userId) {
        GeneralResponse generalResponse = new GeneralResponse();
        // 上传的头像文件不为空
        if(avatar != null) {
            User user = userMapper.selectUserById(userId);

            // 判断文件夹是否存在
            File fileDir = new File(PathUtils.getAvatarPhysicalPath());
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }
            try {
                // 创建新文件保存头像
                String avatarName = System.currentTimeMillis() + avatar.getOriginalFilename();
                File file = new File(fileDir, avatarName);
                boolean isSuccessfullyNewFile = file.createNewFile();
                if (isSuccessfullyNewFile) {
                    // 修改数据库并保存新头像到磁盘
                    userMapper.updateAvatar(user.getId(), avatarName);
                    avatar.transferTo(file);

                    // 如果原来已经有头像，则删除原来的头像
                    if(user.getAvatar() != null) {
                        File oldFile = new File(PathUtils.getAvatarPhysicalPath() + user.getAvatar());
                        oldFile.delete();
                    }
                    generalResponse.setCode(200);
                    generalResponse.setMsg("更换成功！");
                    // 将头像路径返回给前端
                    HashMap<String, String> resData = new HashMap<>();
                    resData.put("avatarPath", PathUtils.getAvatarLogicalPath() + avatarName);
                    generalResponse.setData(resData);
                }else {
                    generalResponse.setCode(500);
                    generalResponse.setMsg("更换失败！");
                }
            } catch (IOException e) {
                e.printStackTrace();
                generalResponse.setCode(500);
                generalResponse.setMsg("更换失败！");
            }
        }else {
            generalResponse.setCode(400);
            generalResponse.setMsg("上传的文件不能为空！");
        }
        return generalResponse;
    }

    /**
     * 修改用户基本信息
     * @param userBasicInfoDTO 用户基本信息
     * @return
     */
    @Override
    public GeneralResponse updateUserBasicInfo(UserBasicInfoDTO userBasicInfoDTO) {
        GeneralResponse generalResponse = new GeneralResponse();

        try {
            userBasicInfoDTO.setUpdateTime(GetTimeUtils.getCurrentTime());
            userMapper.updateUserBasicInfo(userBasicInfoDTO);
            generalResponse.setCode(200);
            generalResponse.setMsg("保存成功！");
        } catch (Exception e) {
            e.printStackTrace();
            generalResponse.setCode(500);
            generalResponse.setMsg("保存失败！");
        }
        return generalResponse;
    }

    /**
     * 修改用户密码
     * @param updatePasswordDTO 用户id和原、新密码
     * @return
     */
    @Override
    public GeneralResponse updatePassword(UpdatePasswordDTO updatePasswordDTO) {
        GeneralResponse generalResponse = new GeneralResponse();
        // 密码不为空或空串或空串的md5加密
        boolean isPasswordNotNull = updatePasswordDTO.getNewPassword() != null
                && updatePasswordDTO.getNewPassword() != ""
                && updatePasswordDTO.getNewPassword() != DigestUtils.md5DigestAsHex("".getBytes());

        if(isPasswordNotNull) {
            try {
                User user = userMapper.selectUserById(updatePasswordDTO.getId());
                // 判断密码是否正确
                if ((DigestUtils.md5DigestAsHex(updatePasswordDTO.getOriginalPassword().getBytes())).equals(user.getPassword()) ) {
                    updatePasswordDTO.setNewPassword(DigestUtils.md5DigestAsHex(updatePasswordDTO.getNewPassword().getBytes()));
                    updatePasswordDTO.setUpdateTime(GetTimeUtils.getCurrentTime());
                    userMapper.updatePassword(updatePasswordDTO);
                    generalResponse.setCode(200);
                    generalResponse.setMsg("修改成功！");
                }else {
                    generalResponse.setCode(400);
                    generalResponse.setMsg("密码错误！");
                }
            } catch (Exception e) {
                e.printStackTrace();
                generalResponse.setCode(500);
                generalResponse.setMsg("修改失败！");
            }
        }else {
            generalResponse.setCode(400);
            generalResponse.setMsg("密码不能为空！");
        }

        return generalResponse;
    }

    /**
     * 修改用户手机号码
     * @param updatePhoneDTO 用户id、新手机号、密码
     * @return
     */
    @Override
    public GeneralResponse updatePhone(UpdatePhoneDTO updatePhoneDTO) {
        GeneralResponse generalResponse = new GeneralResponse();

        // 手机号不为空或空串
        boolean isPhoneNotNull = updatePhoneDTO.getNewPhone() != null && updatePhoneDTO.getNewPhone() != "";
        // 手机号不包含空格
        boolean isPhoneNoSpace = Pattern.matches("^[^\\s]*$", updatePhoneDTO.getNewPhone());

        if(isPhoneNotNull && isPhoneNoSpace) {
            User user = userMapper.selectUserById(updatePhoneDTO.getId());
            // 判断密码是否正确
            if((DigestUtils.md5DigestAsHex(updatePhoneDTO.getPassword().getBytes())).equals(user.getPassword())) {
                updatePhoneDTO.setUpdateTime(GetTimeUtils.getCurrentTime());
                try {
                    userMapper.updatePhone(updatePhoneDTO);
                    generalResponse.setCode(200);
                    generalResponse.setMsg("修改成功！");
                } catch (DuplicateKeyException e) {
                    e.printStackTrace();
                    generalResponse.setCode(400);
                    generalResponse.setMsg("该手机号已被注册！");
                } catch (Exception e) {
                    e.printStackTrace();
                    generalResponse.setCode(500);
                    generalResponse.setMsg("修改失败！");
                }
            }else {
                generalResponse.setCode(400);
                generalResponse.setMsg("密码错误！");
            }
        }else {
            generalResponse.setCode(400);
            generalResponse.setMsg("手机号不能为空或包含空格！");
        }

        return generalResponse;
    }

}
